package com.mldong.auth.data.builder;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.mldong.annotation.DataScope;
import com.mldong.auth.LoginUser;
import com.mldong.auth.data.DataAuthSqlBuilder;
import com.mldong.auth.data.RoleDataScopeEnum;
import com.mldong.web.LoginUserHolder;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

@Component
public class DefaultDataAuthSqlBuilder implements DataAuthSqlBuilder {

    @Override
    public String build(LoginUser loginUser, DataScope dataScope) {
        String tableAlias = dataScope.tableAlias();
        String deptFieldName = StrUtil.toUnderlineCase(dataScope.deptFieldName());
        deptFieldName = StrUtil.isEmpty(tableAlias)?deptFieldName:tableAlias+"."+deptFieldName;
        String userFieldName = StrUtil.toUnderlineCase(dataScope.userFieldName());
        userFieldName = StrUtil.isEmpty(tableAlias)?userFieldName:tableAlias+"."+userFieldName;
        String sqlSegment = "";
        Map<Long,Integer> roleDataScopeMap = loginUser.getRoleDataScopeMap();
        if((ObjectUtil.isNotEmpty(roleDataScopeMap)
                && roleDataScopeMap.size()==1
                && roleDataScopeMap.containsValue(RoleDataScopeEnum.SELF_DATA.getCode())) || ObjectUtil.isEmpty(roleDataScopeMap)
        ){
            // 仅有一个，且是仅查看本人数据权限的，或者未配置有，则只能查看自己的数据
            sqlSegment = StrUtil.format("({} = {})", userFieldName, loginUser.getId());
            return sqlSegment;
        }
        StringBuilder sqlSegmentBuilder = new StringBuilder(sqlSegment);
        String finalDeptFieldName = deptFieldName;
        AtomicBoolean hasDeptDataScope = new AtomicBoolean(false);
        AtomicBoolean hasDeptAndSubDataScope = new AtomicBoolean(false);
        roleDataScopeMap.forEach((roleId, ds)->{
            if(ObjectUtil.equals(ds,RoleDataScopeEnum.CUSTOM_DATA.getCode())){
                // 自定义数据权限,会关联sys_role_dept表
                sqlSegmentBuilder.append(StrUtil.format(" {} in(select dept_id from sys_role_dept where role_id={}) or", finalDeptFieldName,roleId));
            } else if (ObjectUtil.equals(ds,RoleDataScopeEnum.DEPT_DATA.getCode())){
                // 本部门数据权限
                if(!hasDeptDataScope.get()){
                    sqlSegmentBuilder.append(StrUtil.format(" {} = {} or", finalDeptFieldName,loginUser.getDeptId()));
                    hasDeptDataScope.set(true);
                }
            } else if(ObjectUtil.equals(ds,RoleDataScopeEnum.DEPT_AND_SUB_DATA.getCode())){
                // 本部门及以下部门数据权限
                if(!hasDeptAndSubDataScope.get()){
                    List<Long> deptAllSubIdList = LoginUserHolder.getDeptAllSubIdList();
                    if(loginUser.getDeptId()!=null){
                        deptAllSubIdList.add(loginUser.getDeptId());
                    }
                    sqlSegmentBuilder.append(StrUtil.format(" {} in({}) or", finalDeptFieldName,StrUtil.join(",",deptAllSubIdList)));
                    hasDeptAndSubDataScope.set(true);
                }
            }
        });
        // 默认情况下，都可以查看自己的数据
        sqlSegmentBuilder.append(StrUtil.format(" {} = {} or", userFieldName, loginUser.getId()));
        if(sqlSegmentBuilder.length()>0){
            sqlSegment = sqlSegmentBuilder.substring(0,sqlSegmentBuilder.length()-3);
            sqlSegment = StrUtil.format("({})", sqlSegment);
        }
        return sqlSegment;
    }
}
